/*
 * Copyright 2010, 2011 by the University of Richmond, Richmond, VA 23173
 * Written by Eric F. Palmer eric@ericfpalmer.com || epalmer@richmond.edu
 * And other contributors
 * http://www.richmond.edu/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Project files reside at http://code.google.com/p/files-2-exist-db
 */

/*
 * This class extends file so that we can tell if a file that is being written
 * is still growing.  We need this because file locks are not reliable
 * it assumes that there are not long pauses in writing to the file
 *
 * If the system that is writing the file is real slow then raise the milliSecThreshold
 * up a lot (could be even 30 seconds (30000) or something like that
 * and then the file will look like it is still changing
 */

package edu.richmond.is.webservices.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

/**
 *
 * @author root
 */
public class FileChange extends File {
    private long lastFileSize = 0;
    private long lastTimeMilliSec = 0;
    //how long to wait at least before we can tell if a file is still changing
    // this value is critical - if file uploads are really slow this value might
    // need to be really long
    private int  milliSecThreshold = 2000;

    public int getMilliSecThreshold() {
        return this.milliSecThreshold;
    }

    public FileChange(String filename ) {
            super(filename, "");
            this.setLastFileSize();

    }
    public void setMilliSecThreshold(int newValue) {
        if (newValue <= 500) {
            // don't let it set real low
            return;
        }
        this.milliSecThreshold = newValue;
    }

    public void setLastFileSize(){
        this.lastFileSize = this.length();
    }
    public long getLastFileSize(){
        return this.lastFileSize;
    }
    public long getLastTimeMilliSec(){
        return this.lastTimeMilliSec;
    }
    private void setLastTimeMilliSec(){
        this.lastTimeMilliSec = System.currentTimeMillis();
    }
    public boolean isFileSizeChanging(){
        //System.out.println("   length: "+this.length() + " last: "+ this.lastFileSize);
        //System.out.println("   time: "+ System.currentTimeMillis()+ " last: "+ this.lastTimeMilliSec);
        //System.out.println("   "+ this.getName());
        
        if (this.length() != this.lastFileSize)  {
            this.setLastFileSize();
            this.setLastTimeMilliSec();
            // file is changing so reset size and time and proceed
            //System.out.println("\n******* file size is still changing *******\n");
            return true;
        }


        // we only get here because the file sizes are the same
        // so now it is time to let the file time age out
        if ((System.currentTimeMillis() - this.lastTimeMilliSec)
                < this.milliSecThreshold) {
            this.setLastFileSize();
            // we can't tell because not enough time has elasped
            // so assume file is still changing


            //System.out.println("\n******* time change not long enough *******\n");
            return true;
        }
        // if we get here the thresHold time has passed and the file size
        // is stable - so we have to assume the file is done.
        //System.out.println("\n***** File is no longer changing ******\n");
        return false;
    }


    // the fileSize can't be obtained when we are writing to the file unless we open it
    // write to it
    // close it
    // how do we append to it?
    public static void main(String[] args) throws IOException, InterruptedException {

        Timer s = new Timer();

        s.start();

        FileChange myFile = new FileChange("/tmp/12345.txt");
        //write something to the file
        BufferedWriter out = new BufferedWriter(new FileWriter("/tmp/12345.txt", true));
        out.write("start");
        out.close();
        out = null;
        int i = 0;
        //int sleepTime = 100;
        boolean statusFileChange = true;
        while (i < 100) {
            BufferedWriter out2 = new BufferedWriter(new FileWriter("/tmp/12345.txt", true));
            out2.write("something");
            out2.close();
            System.out.println(i);
            System.out.println(myFile.getLastFileSize());
            System.out.println(myFile.length());
            System.out.println(myFile.isFileSizeChanging());

            ++i;
        }
        System.out.println("sleeping 2100");
        Thread.sleep(2100);
        System.out.println(myFile.getLastFileSize());
        System.out.println(myFile.length());
        System.out.println(myFile.isFileSizeChanging());
        System.out.println("sleeping again 4000");
        Thread.sleep(4000);
        System.out.println(myFile.getLastFileSize());
        System.out.println(myFile.length());
        System.out.println(myFile.isFileSizeChanging());


        s.stop();
        System.out.println("et: " + s.getET());



    }



}


